package cz.muni.fi.pa165.languageschool.rest.client.app;

import java.util.HashMap;
import java.util.Map;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

/**
 * Class for manipulation with student entity
 *
 * @author Milos
 */
public class Student {

    //parameters of the student
    Students students;
    String targetBase;
    String firstName;
    String lastName;

    /**
     * Constructor of Student class
     *
     * @param students parameter which is used to define list of students to
     * @param base resources url base
     * which will belong student
     */
    public Student(Students students, String base) {
        this.students = students;
        this.targetBase = base;

    }

    /**
     * This method is used for creating new student on the server. If some
     * problem occur it will inform user about that
     */
    public void newStudent() {
        Response response;
        try {
            Client client = ClientBuilder.newClient();
            WebTarget webTarget = client.target(targetBase).path("students/");

            firstName = Helper.setParam("firstName");
            lastName = Helper.setParam("lastName");

            String input = "{\"type\":\"studentResource\",\"enrolledLectures\":[],"
                    + firstName + ",\"id\":2,"
                    + lastName + "}";

            response = webTarget.request()
                    .post(Entity.entity(input, MediaType.APPLICATION_JSON));

            if (response.getStatus() != 201) {
                throw new RuntimeException("Failed : HTTP error code : "
                        + response.getStatus());
            } else {
                System.out.println("++++++ Student was succesfully created ++++++");
            }
        } catch (Exception ex) {
            System.out.println("We are sorry, something went wrong and now we have : " + ex.getMessage());
        }

    }

    /**
     * updateStudent is used for student updating. User can choose which
     * parameter of the student wants to change. In order to update student user
     * needs to insert id of the student which wants to update. After
     * application will ask him to choose which parameter wants to update.
     * Possibilities: "b" (back), "n" (first name), "l" (last name), "le"
     * (lectures) In case that some error occur application will inform user
     * about that
     */
    public void updateStudent() {

        try {

            Object resp = Helper.getResponse("Set id of student you want to update:", Integer.class);
            if (resp == null) {
                return;
            }
            Integer id = (Integer) resp;

            String student = printStudent(id);
            Map<String, String> map = new HashMap(Helper.toMap(student));
            String out = "";

            printUpdate();
            Object resp1 = Helper.getResponse("Choose which feature you would like to update:", "b", "n", "l", "le");
            switch ((String) resp1) {
                case "b":
                    return;
                case "n":
                    out = Helper.getParam("firstName");
                    map.put("\"firstName\"", out);
                    break;
                case "l":
                    out = Helper.getParam("lastName");
                    map.put("\"lastName\"", out);
                    break;
                case "le":
                    //   System.out.println("We are sorry but this si a trial version. To manage lectures please purchase full version of our product.");
                    return;
                default:
                    ;
                    break;

            }

            Client client = ClientBuilder.newClient();
            WebTarget webTarget = client.target(targetBase).path("students/");

            String input = map.toString();
            input = input.replaceAll("=", ":");

            Response response = webTarget.request()
                    .put(Entity.entity(input, MediaType.APPLICATION_JSON));

            if (response.getStatus() != 201) {
                throw new RuntimeException("Failed : HTTP error code : "
                        + response.getStatus());
            }

            System.out.println("++++++ Course succesfully updated: ++++++");
            printStudent(id);

        } catch (Exception ex) {
            System.out.println("We are sorry, something went wrong and now we have : " + ex.getMessage());
        }
    }

    /**
     * This method is used for deleting student When this method is called user
     * needs to add id of the student which wants to delete Method will inform
     * user if some problem occur
     */
    public void deleteStudent() {

        try {
            Object resp = Helper.getResponse("Set id of student you want to delete:", Integer.class);
            if (resp == null) {
                return;
            }
            Integer id = (Integer) resp;

            Client client = ClientBuilder.newClient();
            WebTarget webTarget = client.target(targetBase)
                    .path("students/" + id.toString());

            Invocation.Builder invocationBuilder
                    = webTarget.request(MediaType.APPLICATION_JSON)
                    .header("accept", "application/json");

            Response response = invocationBuilder.delete();

            if (response.getStatus() != 200) {
                throw new RuntimeException("Failed : HTTP error code : "
                        + response.getStatus());
            }

            String done = response.readEntity(String.class);
            System.out.println(done);
        } catch (Exception ex) {
            System.out.println("We are sorry, something went wrong and now we have : " + ex.getMessage());

        }

    }

    /**
     * Method printStudents() is used for printing all students from the
     * database on the standard output.
     */
    public void printStudents() {
        System.out.println("+++++++ All students +++++++");
        try {
            Client client = ClientBuilder.newClient();
            WebTarget webTarget = client.target(targetBase).path("students/json/");

            Invocation.Builder invocationBuilder
                    = webTarget.request(MediaType.APPLICATION_JSON)
                    .header("accept", "application/json");

            Response response = invocationBuilder.get();

            if (response.getStatus() != 200) {
                throw new RuntimeException("Failed : HTTP error code : "
                        + response.getStatus());
            }

            String resp = response.readEntity(String.class);
            String newResp;
            newResp = resp.replaceAll("\\[|\\]", "");
            resp = newResp.replaceAll("\"type\":\"studentResource\"", "");
            for (String s : resp.split("\\{|\\}")) {
                for (String st : s.split("\\,")) {
                    st.replace("\\}", "");
                    System.out.println(st);
                }
                System.out.println("----");
            }
            System.out.println("+++++++++++++++++++++++++++++++++");
        } catch (Exception ex) {
            System.out.println("We are sorry, something went wrong and now we have : " + ex.getMessage());
        }
    }

    /**
     * This method returns student with given Id
     *
     * @param id id of the student which will be returned
     * @return raw - parameter contains string about student
     */
    public String printStudent(Integer id) {
        String raw;
        System.out.println("+++++++ Requested student: +++++++");
        try {
            Client client = ClientBuilder.newClient();
            WebTarget webTarget = client.target(targetBase)
                    .path("students/json/" + id.toString());

            Invocation.Builder invocationBuilder
                    = webTarget.request(MediaType.APPLICATION_JSON)
                    .header("accept", "application/json");

            Response response = invocationBuilder.get();

            if (response.getStatus() != 200) {
                throw new RuntimeException("Failed : HTTP error code : "
                        + response.getStatus());
            }
            raw = Helper.prinStringResponse(response);
            System.out.println("+++++++++++++++++++++++++++++++++");

            return raw;
        } catch (Exception ex) {
            System.out.println("We are sorry, something went wrong and now we have: " + ex.getMessage());
        }
        return null;

    }

    /**
     * Auxiliary method printUpdate() prints options which can be chosen when
     * student is being updated
     */
    private void printUpdate() {
        System.out.println("_____");
        System.out.println("b - Back");
        System.out.println("n - new First name");
        System.out.println("l - new Last name");
    }
}
